import logging
import logging.handlers
import threading
from typing import List, Dict, Any, Optional

from app.utils.logger import LevelRangeFilter, KeywordFilter


class RealTimeLogManager:
    """实时日志管理器"""
    _instance = None
    _lock = threading.Lock()

    def __new__(cls):
        if cls._instance is None:
            with cls._lock:
                if cls._instance is None:
                    cls._instance = super().__new__(cls)
        return cls._instance

    def __init__(self):
        if not hasattr(self, 'initialized'):
            self.logger_configs = {}  # 存储logger配置
            self.stats = {
                'DEBUG': 0,
                'INFO': 0,
                'WARNING': 0,
                'ERROR': 0,
                'CRITICAL': 0
            }
            self.initialized = True

    def get_all_logger_names(self) -> List[str]:
        """获取所有已注册的logger名称"""
        return list(logging.Logger.manager.loggerDict.keys())

    def get_logger_info(self, logger_name: str) -> Dict[str, Any]:
        """获取特定logger的信息"""
        try:
            logger_obj = logging.getLogger(logger_name)
            return {
                'name': logger_name,
                'level': logging.getLevelName(logger_obj.level),
                'effective_level': logging.getLevelName(logger_obj.getEffectiveLevel()),
                'propagate': logger_obj.propagate,
                'handlers': [self._handler_info(h) for h in logger_obj.handlers],
                'has_parent': logger_obj.parent is not None and logger_obj.parent != logger_obj
            }
        except Exception as e:
            return {
                'name': logger_name,
                'error': str(e)
            }

    def _handler_info(self, handler) -> Dict[str, Any]:
        """获取处理器信息"""
        info = {
            'type': type(handler).__name__,
            'level': logging.getLevelName(handler.level),
            'formatter': str(handler.formatter) if handler.formatter else None,
            'name': getattr(handler, 'name', None),  # 处理器名称
            'filters': []  # 过滤器列表
        }

        # 添加文件处理器的额外信息
        if isinstance(handler, logging.handlers.RotatingFileHandler):
            info['filename'] = handler.baseFilename
            info['max_bytes'] = handler.maxBytes
            info['backup_count'] = handler.backupCount

        # 获取过滤器信息
        if hasattr(handler, 'filters'):
            for filter_obj in handler.filters:
                filter_info = {
                    'type': type(filter_obj).__name__
                }
                # 添加过滤器的特定属性
                if isinstance(filter_obj, logging.Filter):
                    filter_info['name'] = getattr(filter_obj, 'name', None)
                elif isinstance(filter_obj, LevelRangeFilter):
                    filter_info['min_level'] = getattr(filter_obj, 'min_level', None)
                    filter_info['max_level'] = getattr(filter_obj, 'max_level', None)
                elif isinstance(filter_obj, KeywordFilter):
                    filter_info['include_keywords'] = getattr(filter_obj, 'include_keywords', [])
                    filter_info['exclude_keywords'] = getattr(filter_obj, 'exclude_keywords', [])

                info['filters'].append(filter_info)

        return info

    def update_logger_config(self, logger_name: str,
                             level: Optional[str] = None,
                             propagate: Optional[bool] = None) -> bool:
        """更新logger配置"""
        try:
            logger_obj = logging.getLogger(logger_name)

            if level is not None:
                level_num = getattr(logging, level.upper(), None)
                if level_num is not None:
                    # 设置logger级别
                    logger_obj.setLevel(level_num)
                    # 记录到系统日志中
                    logging.info(
                        f"已更新Logger '{logger_name}' 的级别从 {logging.getLevelName(logger_obj.level)} 更改为 {level}")
                else:
                    raise ValueError(f"无效的日志级别: {level}")

            if propagate is not None:
                # 设置logger传播属性
                old_propagate = logger_obj.propagate
                logger_obj.propagate = propagate
                logging.info(f"已更新Logger '{logger_name}' 的传播属性从 {old_propagate} 更改为 {propagate}")

            # 保存配置到内存中
            if logger_name not in self.logger_configs:
                self.logger_configs[logger_name] = {}

            if level is not None:
                self.logger_configs[logger_name]['level'] = level
            if propagate is not None:
                self.logger_configs[logger_name]['propagate'] = propagate

            return True
        except Exception as e:
            logging.getLogger(__name__).error(f"更新logger配置失败: {e}")
            return False

    def add_handler_to_logger(self, logger_name: str, handler_config: Dict[str, Any]) -> bool:
        """为logger添加处理器"""
        try:
            logger_obj = logging.getLogger(logger_name)
            
            # 根据配置创建处理器
            handler_type = handler_config.get('type', 'file')
            level = getattr(logging, handler_config.get('level', 'INFO').upper())
            propagate = handler_config.get('propagate', True)  # 默认为True
            
            if handler_type == 'file':
                filename = handler_config.get('filename', f'../logs/{logger_name}.log')
                max_bytes = handler_config.get('max_bytes', 10485760)  # 10MB
                backup_count = handler_config.get('backup_count', 5)
                
                handler = logging.handlers.RotatingFileHandler(
                    filename, maxBytes=max_bytes, backupCount=backup_count, encoding='utf-8'
                )
            elif handler_type == 'stream':
                handler = logging.StreamHandler()
            else:
                raise ValueError(f"不支持的处理器类型: {handler_type}")
            
            # 设置级别
            handler.setLevel(level)
            
            # 设置格式化器
            formatter = logging.Formatter(
                handler_config.get('format', '%(asctime)s - %(levelname)s - [%(name)s] - %(filename)s:%(lineno)d - %(message)s')
            )
            handler.setFormatter(formatter)
            
            # 设置传播属性
            handler.propagate = propagate
            
            # 添加处理器到logger
            logger_obj.addHandler(handler)
            
            # 从根logger获取console_handler
            root_logger = logging.getLogger()
            console_handler = None
            for h in root_logger.handlers:
                if hasattr(h, 'name') and h.name == 'console_handler':
                    console_handler = h
                    break
            
            # 确保console_handler也处理这些日志
            if console_handler and console_handler not in logger_obj.handlers:
                logger_obj.addHandler(console_handler)
            
            logging.info(f"已为Logger '{logger_name}' 添加处理器: {type(handler).__name__}")
            return True
        except Exception as e:
            logging.getLogger(__name__).error(f"为logger添加处理器失败: {e}")
            return False

    def remove_handler_from_logger(self, logger_name: str, handler_index: int) -> bool:
        """从logger移除处理器"""
        try:
            logger_obj = logging.getLogger(logger_name)

            if 0 <= handler_index < len(logger_obj.handlers):
                handler = logger_obj.handlers[handler_index]
                logger_obj.removeHandler(handler)
                handler.close()  # 关闭处理器
                logging.info(f"已从Logger '{logger_name}' 移除处理器 {type(handler).__name__} (索引: {handler_index})")
                return True
            else:
                logging.warning(f"无效的处理器索引 {handler_index} 对于Logger '{logger_name}'")
                return False
        except Exception as e:
            logging.getLogger(__name__).error(f"从logger移除处理器失败: {e}")
            return False

    def get_stats(self) -> Dict[str, int]:
        """获取日志统计信息"""
        return self.stats.copy()

    def reset_stats(self):
        """重置统计信息"""
        self.stats = {
            'DEBUG': 0,
            'INFO': 0,
            'WARNING': 0,
            'ERROR': 0,
            'CRITICAL': 0
        }

    def add_log_record(self, record: logging.LogRecord):
        """添加日志记录用于统计"""
        levelname = record.levelname
        if levelname in self.stats:
            self.stats[levelname] += 1


# 创建全局实例
log_manager = RealTimeLogManager()


# 自定义日志处理器用于统计
class StatsHandler(logging.Handler):
    def emit(self, record):
        log_manager.add_log_record(record)


# 在模块加载时添加统计处理器到根logger
def setup_stats_handler():
    root_logger = logging.getLogger()
    stats_handler = StatsHandler()
    stats_handler.setLevel(logging.DEBUG)
    root_logger.addHandler(stats_handler)


# 设置统计处理器
setup_stats_handler()
